<template>
  <div>
    <el-button-group>
      <el-button type="primary" :icon="CirclePlus" v-auth="'CreateRole'" @click="formVisible = true"
        >新建角色</el-button
      >
      <el-button type="danger" :icon="Remove" v-auth="'DeleteRole'" @click="handleDeleteList">删除角色</el-button>
      <ImportButton action="/role/import" template="role.xlsx"></ImportButton>
    </el-button-group>
    <x-table
      ref="refTable"
      name="角色"
      :columns="columns"
      :init-sort="{ roleName: 'ascending' }"
      :data="tableData.resp.list"
      :total="tableData.resp.total"
      :loading="tableData.loading"
      @query="handleQuery"
    >
      <template #column-roleStatus="scope">
        <div v-if="!hasFuncKey('Enabled/Disabled')">
          <el-tag v-if="scope.data === 0" type="info">禁用</el-tag>
          <template v-else>启用</template>
        </div>
        <el-switch
          v-else
          :model-value="statusData[scope.row.roleId]"
          inline-prompt
          :active-value="1"
          :inactive-value="0"
          active-text="启用"
          inactive-text="禁用"
          inactive-color="#909399"
          @change="handleChange($event, scope.row)"
        />
      </template>
      <template #column-roleType="scope">
        <el-tag v-if="scope.data === 0" type="danger">系统角色</el-tag>
        <template v-else>自定义角色</template>
      </template>
      <template #column-userCount="scope">
        <el-tooltip class="item" content="点击查看用户" placement="right">
          <span class="user-link" @click="handleOpenUserList(scope.row)">{{ scope.data }}</span>
        </el-tooltip>
      </template>
      <template #column-opera="scope">
        <div class="opera-col">
          <el-link
            v-if="hasFuncKey('AddUser')"
            plain
            type="primary"
            :underline="false"
            :icon="Edit"
            @click="handleOpenUserList(scope.row)"
          >
            <span class="text">分配用户</span>
          </el-link>
          <el-link
            v-if="hasFuncKey('EditRole')"
            plain
            type="primary"
            :underline="false"
            :icon="Edit"
            @click="handleOpenEditForm(scope.row)"
          >
            <span class="text">修改</span>
          </el-link>
          <el-popconfirm
            v-if="hasFuncKey('DeleteRole')"
            :title="`确定删除[ ${scope.row.roleName} ]吗?`"
            @confirm="handleDelete([scope.row.roleId], scope.row.roleName)"
          >
            <template #reference>
              <el-link plain type="danger" :underline="false" :icon="Remove">
                <span class="text">删除</span>
              </el-link>
            </template>
          </el-popconfirm>
        </div>
      </template>
    </x-table>
    <Form ref="refForm" v-model:visible="formVisible" @success="handleFormSuccess" />
    <UserList ref="refUserList" v-model:visible="userListVisible" @update="handleUpdateCount"></UserList>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, ElTag, ElTooltip, ElPopconfirm, ElSwitch } from 'element-plus'
import { CirclePlus, Remove, Edit } from '@element-plus/icons-vue'
import ImportButton from '@/components/import-button/index.vue'
import { confirm } from '@/utils'
import { useColumn } from '@/hooks/column'
import { useAuth } from '@/hooks/auth'
import { roleApi } from '@/api/modules/system/role'
import type { Role } from '@/api/modules/system/role'
import { useRole } from './hook'
import Form from './Form.vue'
import UserList from './UserList.vue'

// 获取权限钩子，用于判断column中的修改和删除按钮 是否显示
const { hasFuncKey, hasFuncKeysCount } = useAuth()

const { refTable, tableData, statusData, handleQuery, filters, handleFormatter } = useRole()
const { columnOpera } = useColumn()
const hasCount = hasFuncKeysCount(['AddUser', 'EditRole', 'DeleteRole'])
const columns = [
  { prop: 'roleCode', label: '角色编号' },
  { prop: 'roleName', label: '角色名称', isGbk: true },
  { prop: 'roleType', label: '角色类型', formatter: handleFormatter, filters: filters.roleType },
  { prop: 'roleStatus', label: '角色状态', formatter: handleFormatter, filters: filters.roleStatus },
  { prop: 'userCount', label: '用户数量', search: false, showOverflowTooltip: false },
  { ...columnOpera, width: 75 * hasCount, isCreate: hasCount > 0 }
]

const refForm = ref()
const formVisible = ref(false)

// 打开修改的窗口
const handleOpenEditForm = (data: Role) => {
  formVisible.value = true
  refForm.value.setFormData(data)
}

// 新建或修改成功后的回调函数，此刷新方法必须写在table组件所在的类文件中，否则执行其方法会出错
const handleFormSuccess = () => {
  refTable.value.refresh()
}

// 删除多个
const handleDeleteList = () => {
  if (refTable.value.selection.length === 0) {
    ElMessage.warning({ message: '请至少勾选列表中的一条数据' })
    return
  }
  const sysTypeNum = refTable.value.selection.filter((item: Role) => {
    return item.roleType === 0
  }).length

  confirm(
    sysTypeNum > 0 ? '您勾选的数据中存在不可删除的[ 系统角色 ], 确定要继续删除其他角色吗?' : '确定要删除角色吗?',
    () => {
      handleDelete(
        refTable.value.selection.map((item: Role) => {
          return item.roleType > 0 ? item.roleId : ''
        })
      )
    }
  )
}
// 执行删除操作
const handleDelete = (ids: string[], name = '') => {
  // log.action('删除角色')
  roleApi.delete(ids).then(resp => {
    if (resp.success) {
      refTable.value.refresh()
      const num = ids.filter(id => id).length
      ElMessage.success(name ? `角色[ ${name} ]已删除` : `${num} 个角色已删除`)
    } else {
      ElMessage.error(resp.message)
    }
  })
}

const handleChange = (val: any, r: Role) => {
  const originVal = statusData[r.roleId]
  if (originVal === undefined || !r.roleId) return
  statusData[r.roleId] = val
  // log.action('激活/禁用角色')
  roleApi.updateRoleStatus({ roleId: r.roleId, roleStatus: val } as Role).then(resp => {
    if (resp.success) {
      r.roleStatus = val
      ElMessage.success(`角色[ ${r.roleName} ]状态已更新`)
    } else {
      statusData[r.roleId] = originVal
      ElMessage.error(resp.message)
    }
  })
}

const refUserList = ref()
const userListVisible = ref(false)
// 打开用户列表窗口
const handleOpenUserList = (data: Role) => {
  userListVisible.value = true
  refUserList.value.setRole(data)
}
const handleUpdateCount = () => {
  refTable.value.refresh()
}
</script>

<style lang="scss" scoped>
.opera-col {
  display: flex;
  justify-content: space-around;
  .text {
    padding: 0 2px;
  }
}
.user-link {
  color: var(--el-color-primary);
  cursor: pointer;
}
:deep(.el-switch__core) {
  width: 50px;
}
</style>
